﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using WorkFlowCore.Authorization;
using WorkFlowCore.Common.Authorization.JWT;
using WorkFlowCore.Common.Tracers;
using WorkFlowCore.Framework.Utils;
using WorkFlowCore.Plugins;

namespace WorkFlowCore.Framework.Authorization
{
    [PluginDescription("说明：第三方token 格式为：[用户信息],[签名]")]
    [PluginDescription("其中 [用户信息] 为 用户信息json序列化后（{\"name\":\"\",\"id\":\"\",\"isManager\":true}）再进行base64处理")]
    [PluginDescription("[签名]为 [用户信息]+[secret-key] 进行 MD5 加密而来")]
    [PluginDescription("参数：secret-key=[签名字符串]")]
    [PluginDescription("参数：sign-type=[签名类型，目前只支持 MD5]")]
    public class CustomerTokenVerifyExtension : ICustomizationVerifyExtension
    {
        private ConfigureContext configureContext = null;
        public async Task Configure(ConfigureContext configureContext)
        {
            this.configureContext = configureContext;
        }

        public VerifyOutput Verify(VerifyInput input)
        {
            using var activity = WorkflowActivitySource.Source?.StartActivity("CustomerTokenVerifyExtension");
            activity?.AddTag("appid", input.AppId ?? "null");

            if (string.IsNullOrWhiteSpace(input.ThirdPartToken))
            {

                return new VerifyOutput { IsValid = false };
            }
            var tokenInfo = input.ThirdPartToken.Split(',');
            if (tokenInfo.Length != 2)
            {

                return new VerifyOutput { IsValid = false };
            }

            var secretKey = configureContext?.Parameters?.GetOrDefault("secret-key") ?? "";
            var signType = configureContext?.Parameters?.GetOrDefault("sign-type") ?? "";//MD5
            var userInfoStr = tokenInfo[0];
            var checkSign = tokenInfo[1].ToLower();
            activity?.AddTag("secretKey", secretKey ?? "null");
            activity?.AddTag("signType", signType ?? "null");
            activity?.AddTag("userInfoStr", userInfoStr ?? "null");
            activity?.AddTag("checkSign", checkSign ?? "null");

            var sign = (signType ?? "").ToLower().Trim() switch
            {
                "md5" => MD5Helper.MD5Encrypt32(userInfoStr + secretKey).ToLower(),
                _ => "",
            };
            //签名不通过
            if (checkSign != sign)
            {

                return new VerifyOutput { IsValid = false };
            }

            //从base64位解析
            userInfoStr = Encoding.UTF8.GetString(Convert.FromBase64String(userInfoStr));

            var userInfo = JsonConvert.DeserializeObject<CustomerTokenInfo>(HttpUtility.UrlDecode(userInfoStr));

            //有过期时间则校验
            if (userInfo.ExpiredTime.HasValue)
            {
                if (userInfo.ExpiredTime.Value < DateTime.Now)
                {

                    return new VerifyOutput { IsValid = false };
                }
            }
            userInfo.AppId = input.AppId;

            return new VerifyOutput { IsValid = true, User = userInfo };
        }

        public class CustomerTokenInfo : AuthorizationUser
        {
            /// <summary>
            /// 过期时间
            /// </summary>
            public DateTime? ExpiredTime { get; set; }
        }
    }
}
